/*
 * Copyright (c) 2021
 * User:魔金多商户商城
 * File:LoginController.java
 * Date:2020/11/27 16:26:27
 */

package com.ruoyi.tc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.google.gson.Gson;
import com.ruoyi.appletsutil.AppletsLoginUtils;
import com.ruoyi.appletsutil.ResultCode;
import com.ruoyi.appletsutil.UnAuthorizedException;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.UnAuth;
import com.ruoyi.common.constant.Rediskey;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.bean.AccessTokenResult;
import com.ruoyi.common.utils.bean.UserInfoResult;
import com.ruoyi.common.utils.bean.WeChatAppletLoginResponse;
import com.ruoyi.common.utils.bean.WechatSetting;
import com.ruoyi.common.utils.http.HttpUtil;
import com.ruoyi.login.AppletConfig;
import com.ruoyi.member.vo.*;
import com.ruoyi.tc.domain.TcMember;
import com.ruoyi.tc.service.ITcMemberService;
import com.ruoyi.util.AES;
import com.ruoyi.util.CommonConstant;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 登录控制器
 *
 * @author SK
 * @since 2018/6/13
 */
@RestController
@Slf4j
@Api(description = "登录接口")
public class TcLoginController {


    /**
     * 注入redis服务
     */
    @Autowired
    private RedisCache redisService;

    /**
     * jwt密钥
     */
    @Value("${token.secret}")
    private String jwtSecretKey;


    /**
     * 注入随机数生成器
     */
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private ITcMemberService memberService;


    /**
     * 头条小程序登陆
     *
     * @param appletLoginRedisParamResponse
     * @return
     */
    @UnAuth
    @PostMapping("/tc/qqLogin")
    @Log(title = "QQ登录", businessType = BusinessType.SELECT)
    public AjaxResult qqLogin(@RequestBody AppletLoginRedisParamResponse appletLoginRedisParamResponse) throws Exception {
        Map<String, Object> res = new HashMap<>();

        String s1 = AppletConfig.QQ.LOGINURL;
        String json = HttpUtil.get(String.format(s1, AppletConfig.QQ.APP_ID, AppletConfig.QQ.APP_SECRET,
                appletLoginRedisParamResponse.getCode()));
        JSONObject object = JSONObject.parseObject(json);
        try {
            if (object.getInteger("errcode") == 0) {
                log.info("qqLogin success [{}]", object);
                String openid = object.get("openid").toString();
                TcMember member = memberService.queryCustomerByappletOpenId(openid, appletLoginRedisParamResponse.getStoreId());
                if (member != null) {
                    res.put("member", member);
                } else {
                    member = new TcMember();
                    member.setSource("9");
                    member.setAppletOpenId(openid);
                    getTcMember(appletLoginRedisParamResponse, member);

                    res.put("member", member);
                }
                //计算用户的相似度

                loginReturn(res, member);
                return AjaxResult.success(res);
            } else {
                log.info("AlipayUserInfoShareResponse fail [{}]", object);
            }
            return AjaxResult.success(res);

        } catch (Exception e) {
            log.error("auth exception", e);
        }
        return null;
    }

    /**
     * 头条小程序登陆
     *
     * @param appletLoginRedisParamResponse
     * @return
     */
    @UnAuth
    @PostMapping("/tc/toutiaoLogin")
    @Log(title = "头条登录", businessType = BusinessType.SELECT)
    public AjaxResult toutiaoLogin(@RequestBody AppletLoginRedisParamResponse appletLoginRedisParamResponse) throws Exception {
        Map<String, Object> res = new HashMap<>();

        String json = HttpUtil.get(String.format(AppletConfig.TOUTIAO.LOGINURL, AppletConfig.TOUTIAO.APP_ID, AppletConfig.TOUTIAO.APP_SECRET,
                appletLoginRedisParamResponse.getCode()));
        JSONObject object = JSONObject.parseObject(json);
        try {
            if ("0".equals(object.get("error").toString())) {
                log.info("toutiaoLogin success [{}]", object);
                String openid = object.get("openid").toString();
                TcMember member = memberService.queryCustomerByappletOpenId(openid, appletLoginRedisParamResponse.getStoreId());
                if (member != null) {
                    res.put("member", member);
                } else {
                    member = new TcMember();
                    member.setAppletOpenId(openid);
                    member.setAliOpenId(object.get("unionid").toString());
                    member.setSource("7");
                    getTcMember(appletLoginRedisParamResponse, member);
                    res.put("member", member);
                }
                //计算用户的相似度
                loginReturn(res, member);
                return AjaxResult.success(res);
            } else {
                log.info("AlipayUserInfoShareResponse fail [{}]", object);

            }
            return AjaxResult.error(object.get("message").toString());

        } catch (Exception e) {
            log.error("auth exception", e);
        }
        return null;
    }

    /**
     * 支付宝小程序登陆
     *
     * @param appletLoginRedisParamResponse
     * @return
     */
    @UnAuth
    @PostMapping("/tc/alipayLogin")
    @Log(title = "支付宝登录", businessType = BusinessType.SELECT)
    public AjaxResult alipayLogin(@RequestBody AppletLoginRedisParamResponse appletLoginRedisParamResponse) {
        Map<String, Object> res = new HashMap<>();

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                AppletConfig.ALIPAY.appId, AppletConfig.ALIPAY.privateKey,
                "JSON", "utf-8", AppletConfig.ALIPAY.alipayPublicKey, "RSA2");


        //获取uid&token
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");//值为authorization_code时，代表用code换取；值为refresh_token时，代表用refresh_token换取
        request.setCode(appletLoginRedisParamResponse.getCode());
        try {
            AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                log.info("auth success [{}]", JSONObject.toJSONString(response));

                AlipayUserInfoShareRequest alipayUserInfoShareRequest = new AlipayUserInfoShareRequest();
                AlipayUserInfoShareResponse alipayUserInfoShareResponse = alipayClient.execute(alipayUserInfoShareRequest, response.getAccessToken());
                if (alipayUserInfoShareResponse.isSuccess()) {
                    log.info("AlipayUserInfoShareResponse success [{}]", JSONObject.toJSONString(alipayUserInfoShareResponse));

                    TcMember member = memberService.queryCustomerByappletOpenId(alipayUserInfoShareResponse.getUserId(), appletLoginRedisParamResponse.getStoreId());
                    if (member != null) {
                        res.put("member", member);
                    } else {
                        member = new TcMember();
                        member.setDetailaddress(alipayUserInfoShareResponse.getProvince() + "-" + alipayUserInfoShareResponse.getCity());
                        member.setNickname(alipayUserInfoShareResponse.getNickName());
                        member.setImage(alipayUserInfoShareResponse.getAvatar());
                        member.setGender(alipayUserInfoShareResponse.getGender().equalsIgnoreCase("m") ? "1" : "0");
                        member.setAliOpenId(response.getAlipayUserId());
                        member.setSource("6");
                        member.setAppletOpenId(alipayUserInfoShareResponse.getUserId());
                        setMember(member, appletLoginRedisParamResponse.getStoreId(), appletLoginRedisParamResponse.getRecommondCode());

                        res.put("member", member);
                    }
                    //计算用户的相似度
                    loginReturn(res, member);

                    return AjaxResult.success(res);
                } else {
                    log.info("AlipayUserInfoShareResponse fail [{}]", JSONObject.toJSONString(alipayUserInfoShareResponse));
                }
                return AjaxResult.success(alipayUserInfoShareResponse);
            } else {
                log.info("auth fail [{}]", JSONObject.toJSONString(response));
            }
        } catch (AlipayApiException e) {
            log.error("auth exception", e);
        }
        return null;
    }


    /**
     * 会员手机验证码登录注册
     *
     * @param loginParams 登录参数
     * @return -1 用户名或密码错误  -2 账号冻结  -3 账号锁定 1 成功  -4 验证码错误
     */
    @PostMapping("/tc/loginByCode")
    @UnAuth
    @ResponseBody
    @ApiOperation(value = "会员登录", notes = "会员登录（不需要认证）")
    @ApiResponses({
            @ApiResponse(code = 200, message = "result: -1 用户名或密码错误  -2 账号冻结  -3 账号锁定 1 成功  -4 验证码错误  token:放登录成功后的token", response = Map.class)
    })
    @Log(title = "会员手机验证码登录注册", businessType = BusinessType.SELECT)
    public AjaxResult loginByCode(@RequestBody LoginParams loginParams, HttpServletRequest request) {

        log.info("loginByCode :checkAppletOAuthParams code=" + loginParams.getCode());
        Map<String, Object> res = new HashMap<>();
        TcMember member = memberService.queryCustomerByName(loginParams.getMobile(), loginParams.getStoreId());
        String originCode = redisService.getValue(String.format("%s_%s", CommonConstant.APPLET_REGISTER_CODE_KEY, loginParams.getMobile()));
        if (StringUtils.isEmpty(loginParams.getCode())) {
            log.error("loginByCode fail due to code is error...");
            return AjaxResult.error("loginByCode fail due to code is error...");
        }
        if (StringUtils.isEmpty(loginParams.getMobile())) {
            log.error("loginByCode fail due to mobile  is empty...");
            return AjaxResult.error("loginByCode fail due to mobile  is empty...");
        }
        if (!originCode.equals(loginParams.getCode())) {
            log.error("loginByCode fail due to code is error...");
            return AjaxResult.error("loginByCode fail due to code is error...");
        }
        if (member != null) {
            res.put("member", member);
        } else {
            member = new TcMember();
            member.setSource("3");
            member.setUsername(loginParams.getMobile());
            setMember(member, loginParams.getStoreId(), loginParams.getRecommondCode());
            res.put("member", member);
        }
        //计算用户的相似度
        loginReturn(res, member);

        return AjaxResult.success(res);
    }

    /**
     * 会员登录
     *
     * @param loginParams 登录参数
     * @return -1 用户名或密码错误  -2 账号冻结  -3 账号锁定 1 成功  -4 验证码错误
     */
    @PostMapping("/tc/logout")
    @UnAuth
    @ResponseBody
    @ApiOperation(value = "会员退出", notes = "会员登录（不需要认证）")
    @ApiResponses({
            @ApiResponse(code = 200, message = "result: -1 用户名或密码错误  -2 账号冻结  -3 账号锁定 1 成功  -4 验证码错误  token:放登录成功后的token", response = Map.class)
    })
    @Log(title = "会员退出", businessType = BusinessType.SELECT)
    public AjaxResult logout(@RequestBody LoginParams loginParams, HttpServletRequest request) {
        redisService.deleteObject(String.format(Rediskey.TOKEN, getToken(request)));
        return AjaxResult.success();
    }

    /**
     * 公众号通过code登录
     *
     * @param 。开发者需要在开发者服务器后台调用 api，使用 code 换取 openid 和 session_key 等信息
     * @return 登录信息
     */
    @UnAuth
    @ResponseBody
    @RequestMapping("/tc/loginByWeiXinCode")
    @ApiOperation(value = "公众号获取登录信息", notes = "公众号获取登录信息（不需要认证）", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", dataType = "string", name = "code", value = "用户登录凭证"),
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "登录信息", response = AppletLoginInfo.class)
    })
    @Log(title = "公众号获取登录", businessType = BusinessType.SELECT)
    public AjaxResult loginByWeiXinCode(String code, @RequestParam(value = "recommondCode", required = false) String recommondCode,
                                        @RequestParam(value = "storeId", required = false, defaultValue = "0") long storeId, HttpServletRequest request) {
        log.info("getLoginInfo :checkAppletOAuthParams code=" + code);
        Map<String, Object> res = new HashMap<>();

        WechatSetting wechatSetting = new WechatSetting();
        wechatSetting.setAppId(AppletConfig.WECHATH5.appId);
        wechatSetting.setAppSecret(AppletConfig.WECHATH5.appSecret);
        if (!wechatSetting.checkAppletOAuthParams()) {
            log.error("getLoginInfo fail:checkAppletOAuthParams fail");
            return AjaxResult.error("getLoginInfo fail:checkAppletOAuthParams fail");
        }
        WeChatAppletLoginResponse weChatAppletLoginResponse = WechatUtils.getLoginInfo(code, wechatSetting);
        if (Objects.isNull(weChatAppletLoginResponse)) {
            log.error("getLoginInfo fail: getLoginInfo fail");
            return AjaxResult.error("getLoginInfo fail: getLoginInfo fail");
        }

        log.info("getOpenId : openid==" + weChatAppletLoginResponse.getOpenid());
        TcMember member = memberService.queryCustomerByh5OpenId(weChatAppletLoginResponse.getOpenid(), storeId);
        if (member != null) {
            res.put("member", member);
        } else {
            member = new TcMember();
            member.setH5OpenId(weChatAppletLoginResponse.getOpenid());
            member.setSource("3");
            UserInfoResult userInfo = WechatUtils.getUserInfo(weChatAppletLoginResponse.getAccess_token(), weChatAppletLoginResponse.getOpenid());
            if (userInfo != null) {
                member.setNickname(userInfo.getNickname());
                member.setImage(userInfo.getHeadimgurl());
                member.setGender(userInfo.getSex());
            }

            setMember(member, storeId, recommondCode);
            res.put("member", member);
        }
        //计算用户的相似度
        loginReturn(res, member);
        return AjaxResult.success(res);
    }

    /**
     * 小程序获取openid 并更新当前用户，也就是手机登录后小程序授权
     *
     * @param 。开发者需要在开发者服务器后台调用 api，使用 code 换取 openid 和 session_key 等信息
     * @return 登录信息
     */
    @UnAuth
    @ResponseBody
    @RequestMapping("/tc/getOpenId")
    @ApiOperation(value = "小程序获取登录信息", notes = "小程序获取登录信息（不需要认证）", httpMethod = "POST")
    @Log(title = "getOpenId", businessType = BusinessType.SELECT)
    public AjaxResult getOpenId(@RequestBody AppletLoginRedisParamResponse appletLoginRedisParamResponse, HttpServletRequest request) {

        WechatSetting wechatSetting = new WechatSetting();
        wechatSetting.setAppId(AppletConfig.WECHATAPPLET.appId);
        wechatSetting.setAppSecret(AppletConfig.WECHATAPPLET.appSecret);
        if (!wechatSetting.checkAppletOAuthParams()) {
            log.error("getLoginInfo fail:checkAppletOAuthParams fail");
            return AjaxResult.error("getLoginInfo fail:checkAppletOAuthParams fail");
        }
        WeChatAppletLoginResponse weChatAppletLoginResponse = WeChatAppletUtils.getLoginInfo(appletLoginRedisParamResponse.getCode(), wechatSetting);
        if (Objects.isNull(weChatAppletLoginResponse)) {
            log.error("getLoginInfo fail: getLoginInfo fail");
            return AjaxResult.error("getLoginInfo fail: getLoginInfo fail");
        }
        return AjaxResult.success(weChatAppletLoginResponse);
    }

    /**
     * 小程序登录
     *
     * @param 。开发者需要在开发者服务器后台调用 api，使用 code 换取 openid 和 session_key 等信息
     * @return 登录信息
     */
    @UnAuth
    @ResponseBody
    @RequestMapping("/tc/mpWechatLogin")
    @ApiOperation(value = "小程序获取登录信息", notes = "小程序获取登录信息（不需要认证）", httpMethod = "POST")
    @Log(title = "微信小程序获取登录", businessType = BusinessType.SELECT)
    public AjaxResult mpWechatLogin(@RequestBody AppletLoginRedisParamResponse appletLoginRedisParamResponse, HttpServletRequest request) {
        Map<String, Object> res = new HashMap<>();
        String openid = appletLoginRedisParamResponse.getOpenId();
        TcMember member = memberService.queryCustomerByappletOpenId(openid, appletLoginRedisParamResponse.getStoreId());
        if (member != null) {
            res.put("member", member);
            setMember(appletLoginRedisParamResponse, member);
            member.setModifyTime(new Date());
            memberService.updateTcMember(member);
        } else {
            member = new TcMember();
            member.setSource("5");
            member.setAppletOpenId(openid);
            getTcMember(appletLoginRedisParamResponse, member);
            res.put("member", member);
        }
        //计算用户的相似度
        loginReturn(res, member);
        res.put("sessionKey", appletLoginRedisParamResponse.getSessionKey());
        return AjaxResult.success(res);

    }

    private void setMember(AppletLoginRedisParamResponse appletLoginRedisParamResponse, TcMember member) {
        UserInfo userInfo = appletLoginRedisParamResponse.getUserInfo();
        if (userInfo != null) {
            member.setNickname(userInfo.getNickName());
            member.setImage(userInfo.getAvatarUrl());
            member.setGender(userInfo.getGender());
            if (StringUtils.isNotEmpty(userInfo.getProvince())) {
                member.setDetailaddress(userInfo.getCountry() + "-" + userInfo.getProvince() + "-" + userInfo.getCity());
            } else {
                member.setDetailaddress(userInfo.getCountry());
            }
        } else {
            member.setNickname(member.getRelename());
            member.setUsername(member.getRelename());
        }
    }


    @PostMapping("/tc/wxapp/bindingPhone")
    @ApiOperation(value = "小程序绑定手机号", notes = "小程序绑定手机号")
    @Log(title = "小程序绑定手机号", businessType = BusinessType.SELECT)
    public AjaxResult phone(@Validated @RequestBody AppletLoginRedisParamResponse param, HttpServletRequest request) {

        Long uid = AppletsLoginUtils.getInstance().getCustomerId(request);
        TcMember userQueryVo = memberService.queryCustomerInfoById(uid);
        if (userQueryVo == null) {
            return AjaxResult.error("请先登录!");
        }
        if ("1".equals(userQueryVo.getIsMobileVerification())) {
            return AjaxResult.error("您的账号已经绑定过手机号码");
        }

        //解析手机号
        WxPhoneInfo wxPhoneInfo = null;

        try {
            String result = AES.wxDecrypt(param.getEncryptedData(), param.getSessionKey(), param.getIv());
            Gson gson = new Gson();
            wxPhoneInfo = gson.fromJson(result, WxPhoneInfo.class);
            if (wxPhoneInfo != null) {
                TcMember newUserQueryVo = memberService.queryCustomerByName(wxPhoneInfo.getPhoneNumber(), param.getStoreId());
                if (newUserQueryVo != null) {
                    return AjaxResult.error("手机号码已被绑定");
                }
                userQueryVo.setMobile(wxPhoneInfo.getPhoneNumber());
                userQueryVo.setIsMobileVerification("1");
                memberService.updateTcMember(userQueryVo);
                return AjaxResult.success(wxPhoneInfo.getPhoneNumber());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error("绑定失败");

    }

    /**
     * 检测token
     */
    @RequestMapping("/tc/verifyToken")
    @UnAuth
    @ResponseBody
    public AjaxResult verifyToken(String token, HttpServletRequest request) {
        Map map = new HashMap();
        map.put("opentop", true);
        return AjaxResult.success(map);
    }

    /**
     * app微信登陆
     *
     * @param openid
     * @param sex
     * @param headimgurl
     * @param unionid
     * @param nickname
     * @param recommondCode
     * @param city
     * @param storeId
     * @param source
     * @return
     */
    @UnAuth
    @ResponseBody
    @RequestMapping("/tc/appLogin")
    @Log(title = "appLogin", businessType = BusinessType.SELECT)
    public Object appLogin(@RequestParam String openid,
                           @RequestParam Integer sex,
                           @RequestParam String headimgurl,
                           @RequestParam String unionid,
                           @RequestParam String nickname,
                           @RequestParam(value = "recommondCode", required = false) String recommondCode,
                           @RequestParam String city,
                           @RequestParam(value = "storeId", required = false, defaultValue = "0") long storeId,
                           @RequestParam Integer source) {

        if (openid == null || "".equals(openid)) {
            return AjaxResult.error("openid为空");
        }
        try {
            Map<String, Object> res = new HashMap<>();
            TcMember member = memberService.queryCustomerByappOpenId(openid, storeId);
            if (member != null) {
                res.put("member", member);
            } else {
                member = new TcMember();
                member.setNickname(nickname);
                member.setAppOpenId(openid);
                member.setAliOpenId(unionid);
                member.setImage(headimgurl);
                member.setGender(sex + "");
                member.setSource("2");

                setMember(member, storeId, recommondCode);
                res.put("member", member);
            }
            //计算用户的相似度
            loginReturn(res, member);

            return AjaxResult.success(res);
        } catch (ServiceException e) {
            return AjaxResult.error("用户名或密码错误");
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }

    }

    /**
     * 绑定公众号
     */
    @GetMapping("/tc/wechatlogin")
    @UnAuth
    @ApiIgnore
    @Log(title = "wechatlogin", businessType = BusinessType.SELECT)
    public void wechatLogin(String code, String state, long storeId, HttpServletResponse response, HttpServletRequest request) throws Exception {
        log.debug("wechatLogin and code:{} \r\n state:{} \r\n ", code, state);
        WechatSetting wechatSetting = new WechatSetting();
        wechatSetting.setAppId(AppletConfig.WECHATH5.appId);
        wechatSetting.setAppSecret(AppletConfig.WECHATH5.appSecret);
        //wechatSetting.setUrl(AppletConfig.WECHATH5.);

        //获取accesstoken
        AccessTokenResult weChatAppletLoginResponse = WechatUtils.getAccessToken(code, state, wechatSetting);
        if (ObjectUtils.isEmpty(weChatAppletLoginResponse) || weChatAppletLoginResponse.isError()) {
            log.error("wechatLogin error : getAccessToken fail");
        }
        TcMember member = memberService.queryCustomerByh5OpenId(weChatAppletLoginResponse.getOpenid(), storeId);
        if (member != null) {

        } else {
            member = memberService.queryCustomerWithNoPasswordById(AppletsLoginUtils.getInstance().getCustomerId(request));
            if (member != null) {
                member.setH5OpenId(weChatAppletLoginResponse.getOpenid());
                memberService.updateTcMember(member);
            }
        }
        response.sendRedirect(state);
    }


    /**
     * 获取token
     *
     * @param request request
     * @return token
     */
    private String getToken(HttpServletRequest request) {
        // 认证信息在header 中的key
        final String authHeader = request.getHeader("Authorization");

        if (Objects.isNull(authHeader) || !authHeader.startsWith("Bearer")) {
            log.info("getClaims fail :Authorization fail ");
            throw new UnAuthorizedException(ResultCode.NOT_AUTHORIZED);
        }
        return authHeader.length() >= 7 ? authHeader.substring(7) : authHeader.substring(6);
    }

    private void getTcMember(AppletLoginRedisParamResponse appletLoginRedisParamResponse, TcMember member) {
        setMember(appletLoginRedisParamResponse, member);
        setMember(member, appletLoginRedisParamResponse.getStoreId(), appletLoginRedisParamResponse.getRecommondCode());
    }

    private void setMember(TcMember member, long storeId, String recommondCode) {
        member.setStoreId(storeId);
        member.setMobile(RandomMathLetter.randomPhone());
        member.setRelename("魔金" + RandomMathLetter.randomString(4));
        member.setPassword("123456");
        member.setConsumptionAmount(BigDecimal.ZERO);
        //设置自己的推荐码
        member.setRecommondCode(recommondCode);
        memberService.insertTcMember(member);

    }

    private void loginReturn(Map<String, Object> res, TcMember member) {

        final StringBuilder sb = new StringBuilder();
        sb.append(Jwts.builder().setSubject(member.getUsername())
                .compressWith(CompressionCodecs.DEFLATE)
                .signWith(SignatureAlgorithm.HS256, jwtSecretKey)
                .setIssuedAt(new Date())
                .claim("userName", member.getUsername())
                .claim("nickName", member.getNickname())
                .claim("releName", member.getRelename())
                .claim("id", member.getId())
                .setExpiration(Date.from(Instant.now().plus(1, ChronoUnit.HOURS))) // 有效期1小时
                .compact());

        redisService.putToRedis(String.format(Rediskey.TOKEN, sb.toString()), JSON.toJSONString(member), 100, TimeUnit.DAYS);
        res.put("access_token", sb.toString());
        res.put("refresh_token", sb.toString());
    }

    /**
     * 校验手机号码是否存在
     *
     * @param mobile 手机号码
     * @return 存在返回>0  不存在返回0
     */
    @ResponseBody
    @RequestMapping("/tc/checkmobileexist")
    @UnAuth
    @ApiOperation(value = "校验手机号码是否存在", notes = "校验手机号码是否存在（不需要认证）", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "form", dataType = "string", name = "mobile", value = "手机号码"),
    })
    @ApiResponses({
            @ApiResponse(code = 200, message = "存在返回>0  不存在返回0", response = Integer.class)
    })
    @Log(title = "校验手机号码是否存在", businessType = BusinessType.SELECT)
    public AjaxResult checkMobileExist(String mobile, long storeId) {
        return AjaxResult.success(memberService.isMobileExist(mobile, storeId));
    }

    /**
     * 发送短信验证码
     * r
     *
     * @param mobile 手机号码
     * @return 0 成功 1 失败 -1 手机号码已经存在
     */
    @UnAuth
    @RequestMapping(value = "/tc/sendmobilecode")
    @ResponseBody
    @Log(title = "发送短信验证码", businessType = BusinessType.SELECT)
    public AjaxResult sendSmsCode(@RequestParam(value = "storeId", required = false, defaultValue = "0") long storeId, String mobile) {
        redisService.putToRedis(String.format("%s_%s", CommonConstant.APPLET_REGISTER_CODE_KEY, mobile), "1234", 5000, TimeUnit.MINUTES);
        return AjaxResult.success("1234");
        //   return AjaxResult.success(registerServiceApi.sendRegisterSmsCode(mobile,storeId, code -> redisService.putToRedis(String.format("%s_%s", CommonConstant.APPLET_REGISTER_CODE_KEY, mobile), code, 5, TimeUnit.MINUTES)));
    }


    /**
     * 用户注册
     *
     * @return -1 手机验证码错误 -2 参数错误 0 失败  成功>0  -3 手机号码已存在 -10 推荐人不存在
     */
    @UnAuth
    @RequestMapping("/tc/register")
    @ResponseBody
    @ApiOperation(value = "用户注册", notes = "用户注册（不需要认证）", httpMethod = "POST")

    @ApiResponses({
            @ApiResponse(code = 200, message = "-1 手机验证码错误 -2 参数错误 0 失败  成功>0  -3 手机号码已存在 -10 推荐人不存在", response = Integer.class)
    })
    @Log(title = "用户注册", businessType = BusinessType.SELECT)
    public AjaxResult tcregister(@RequestBody TcLoginController.TcRegisterData registerData) {
        int res = 0;
        try {
            res = memberService.registerCustomer(registerData.getStoreId(), registerData.getMobile(), registerData.getPassword(), registerData.getCode(),
                    redisService.getValue(String.format("%s_%s", CommonConstant.APPLET_REGISTER_CODE_KEY, registerData.getMobile())), registerData.getRecommendCode());

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(res);
        }
        if (res > 0) {
            return AjaxResult.success(res);
        }
        if (res == -1) {
            return AjaxResult.error(res, "手机验证码错误");
        }
        if (res == -2) {
            return AjaxResult.error(res, "参数错误");
        }
        if (res == -3) {
            return AjaxResult.error(res, "手机号码已存在");
        }
        if (res == -10) {
            return AjaxResult.error(res, "推荐人不存在");
        }
        return AjaxResult.error(res);
    }


    /**
     * 用户注册实体
     */
    @Data
    @ApiModel(description = "用户注册实体")
    private static class TcRegisterData {

        /**
         * 手机号码
         */
        @ApiModelProperty(value = "手机号码")
        private String mobile;

        /**
         * 密码
         */
        @ApiModelProperty(value = "密码")
        private String password;

        /**
         * 手机验证码
         */
        @ApiModelProperty(value = "手机验证码")
        private String code;

        /**
         * 推荐码
         */
        @ApiModelProperty(value = "推荐码")
        private String recommendCode;

        private long storeId;

    }
}
